package com.komodo.island.gdx.game.komodobalance;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.actors.Image;
import com.komodo.island.gdx.Art;
import com.komodo.island.gdx.Constants;
import com.komodo.island.gdx.KomodoIsland;
import com.komodo.island.gdx.Persistence;
import com.komodo.island.gdx.dialog.LoseDialog;
import com.komodo.island.gdx.dialog.WinDialog;
import com.komodo.island.gdx.game.Time;
import com.komodo.island.gdx.screen.GameScreen;
import com.komodo.island.gdx.screen.Screen;

public class GameBalance extends GameScreen {
	public int inputX;
	public int inputY;
	public int timeLimit;
	public boolean isFinish;
	public Balance balance;
	public List<Item> itemList;
	private int screenWidth;
	private Time time;
	private double second;
	private Random rand;
	private List<Integer> deleteList;
	private Sprite finishButton;
	public static Texture komodoBalanceTexture;
	public Sprite targetKG;
	public Sprite backgroundSprite;

	public TargetIndicator target;
	
	public Time gameTime;

	public Sound in;

	@Override
	public void init(KomodoIsland komodoIsland, Texture texture) {
		// TODO Auto-generated method stusb
		super.init(komodoIsland, texture);

		previousScreen = komodoIsland.scientistScreen;
	}

	public void onGameStart() {
		// TODO Auto-generated method stub
		// bestScore = Persistence.getBestScore(Persistence.BALANCE);
		camera = new OrthographicCamera(480,320);
		rand = new Random();

		score = 0;

		int minimumWeight = 40;
		int kw = minimumWeight + rand.nextInt(100);
		balance = new Balance(kw);
		isFinish = false;
		time = new Time(0, 3);
		second = time.getSecond();
		itemList = new ArrayList<Item>();
		for (int i = 0; i < 5; i++) {
			itemList.add(new Item(3+rand.nextInt(15), 9 + rand.nextInt(12), rand
					.nextInt(Gdx.graphics.getWidth()*9/10), rand));
		}
		inputX = 9999;
		inputY = 9999;

	}

	@Override
	public void hide() {
		// TODO Auto-generated method stub
		super.hide();
		try {
			if (Persistence.sound) {
				if (komodoIsland.balance.isPlaying()) {
					komodoIsland.balance.stop();
				}
			} else {

			}
		} catch (Exception e) {

		}
	}

	@Override
	public void show() {
		// TODO Auto-generated method stub
		super.show();
		try {
			if (Persistence.sound) {
				if (!komodoIsland.balance.isPlaying()) {
					komodoIsland.balance.play();
				}
			} else {

			}
		} catch (Exception e) {

		}
		
		if (winDialog == null)
			this.winDialog = new BalanceWinDialog(480, 320, true, this,
					komodoIsland.dialogTexture,komodoIsland);
		if (loseDialog == null)
			this.loseDialog = new BalanceLoseDialog(480, 320, true, this,
					komodoIsland.dialogTexture,komodoIsland);
	}

	public void onGameRunning() {
		// TODO Auto-generated method stub
		camera.update();
		batch.setProjectionMatrix(camera.combined);

		if (!isFinish) {
			time.runTime();
			gameTime.runTime();
			// Item Balance
			if (second - time.getSecond() >= 0.09) {
				second = time.getSecond();
				for (int i = 0; i < itemList.size(); i++) {
					if (itemList.get(i).isReady) {
						itemList.get(i).itemDrop();
					}
					if (balance.isItemIn(itemList.get(i))) {
						if (Persistence.sound)
							in.play(1);
						balance.increaseWeight(itemList.get(i).weight);
						itemList.get(i).isReady = false;
						itemList.get(i).itemRectangle.y = Gdx.graphics
								.getHeight() / -5;
						itemList.get(i).itemSprite.setPosition(
								itemList.get(i).itemRectangle.x,
								itemList.get(i).itemRectangle.y);
					} else if (itemList.get(i).itemRectangle.y >= Gdx.graphics
							.getHeight()) {
						itemList.get(i).isReady = false;
						itemList.get(i).itemRectangle.y = Gdx.graphics
								.getHeight() / -5;
						itemList.get(i).itemSprite.setPosition(
								itemList.get(i).itemRectangle.x,
								itemList.get(i).itemRectangle.y);
					}
				}
			}

			// Item Time
			if (Math.ceil(time.getSecond()) == 0) {
				int i = 0;
				boolean temp = false;
				while (i < 5 && !temp) {
					if (itemList.get(i).isReady == false) {
						temp = true;
						itemList.get(i).isReady = true;
						itemList.get(i).weight = 3+rand.nextInt(15);
						itemList.get(i).setSprite();

						itemList.get(i).acceleration = 10 + rand.nextInt(20);
						itemList.get(i).itemRectangle.x = rand.nextInt(screenWidth*9/10);
						
						itemList.get(i).itemSprite.setPosition(
								itemList.get(i).itemRectangle.x,
								itemList.get(i).itemRectangle.y);
					}
					i++;
				}
				time.setSecond(0.5 + rand.nextInt(1));
				second = 2;
			}

			// Balance
			if (balance.isTouched()) {
				if (inputX == 9999 && inputY == 9999) {
					inputX = Gdx.input.getX();
					inputY = Gdx.input.getY();
				}
			}

			if (!Gdx.input.isTouched()) {
				inputX = 9999;
				inputY = 9999;
			}

			if (inputX != 9999 && inputY != 9999) {
				balance.moveBalance(Gdx.input.getX() - inputX);
				inputX = Gdx.input.getX();
			}

			// Finish Button Touched
			if (isFinishButtonPressed()) {
				isFinish = true;
				int delta = Math.abs(balance.basketWeight
						- balance.komodoWeight);
				score += balance.komodoWeight * 100;
				score += 100 * gameTime.getSecond();

				if (delta <= 0) {
					score += 20000;
					setGameToWin();
					((BalanceWinDialog) winDialog).setFinishing();
				} else if (delta <= 1) {
					score += 15000;
					setGameToWin();
					((BalanceWinDialog) winDialog).setFinishing();
				} else if (delta <= 5) {
					score += 12000;
					setGameToWin();
					((BalanceWinDialog) winDialog).setFinishing();
				} else if (delta <= 10) {
					score += 10000;
					setGameToWin();
					((BalanceWinDialog) winDialog).setFinishing();
				} else if (delta <= 20) {
					score += 5000;
					setGameToWin();
					((BalanceWinDialog) winDialog).setFinishing();
				} else {
					// score = 0;
					setGameToLose();
					((BalanceLoseDialog) loseDialog).setFinishing();
				}

			}

			// Over Weight
			if (balance.isOverWeight()) {
				isFinish = true;
				score = 0;
				setGameToLose();
			}
			

			if (gameTime.getMinute() == 0 && (Math.ceil(gameTime.getSecond()) == 0)) {
				isFinish = true;
				score = 0;
				setGameToLose();
			}
		} else {
				if (Math.abs(balance.basketWeight - balance.komodoWeight) >= 10) {
					onGameWin();
				} else {
					onGameLose();
				}
		}
		batch.begin();
		if (!isFinish) {
			backgroundSprite.draw(batch);
			for (int z = 0; z < itemList.size(); z++) {
				itemList.get(z).itemSprite.draw(batch);
			}
			targetKG.draw(batch);
			balance.basketSprite.draw(batch);
			finishButton.draw(batch);
		}
		batch.end();
		target.draw();
		Art.drawString("Time : " + Art.decimal2.format(gameTime.getSecond()), 0, -2);

	}

	public void onGameWin() {

	}

	public void onGameLose() {

	}

	public void onGamePause() {

	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		super.dispose();

	}

	@Override
	public void cleanResScreen() {
		// TODO Auto-generated method stub
		super.cleanResScreen();
		try {
			komodoBalanceTexture.dispose();
			in.dispose();
			komodoBalanceTexture=null;
			
		} catch (Exception e) {

		}
	}
	
	@Override
	public void exitScreen() {
		// TODO Auto-generated method stub
		try {
			komodoBalanceTexture.dispose();
			in.dispose();
			komodoBalanceTexture=null;
			in = null;
//			System.gc();
			
		} catch (Exception e) {

		}
		super.exitScreen();
	}

	public boolean isFinishButtonPressed() {
		return (Gdx.input.getX() >= (Gdx.graphics.getWidth() / 5 * 2)
				&& Gdx.input.getX() <= (Gdx.graphics.getWidth() / 5 * 3)
				&& Gdx.input.getY() <= (Gdx.graphics.getHeight() / 4)
				&& Gdx.input.getY() >= 0 && Gdx.input.justTouched());
	}

	@Override
	protected void onGameLoading() {
		// TODO Auto-generated method stub

		if (in == null) {
			in = Gdx.audio.newSound(Gdx.files.internal("sfx/balance/in.wav"));
		}

		if (komodoIsland.balance == null) {
			komodoIsland.balance = Gdx.audio.newMusic(Gdx.files
					.internal("bgm/balance.wav"));
			komodoIsland.balance.setLooping(true);
			komodoIsland.balance.setVolume(0.5f);
		}

		if (Persistence.sound) {
			try {
				if (!komodoIsland.balance.isPlaying()) {
					komodoIsland.balance.play();
				}
			} catch (Exception e) {

			}
		}

		if (komodoBalanceTexture == null)
			komodoBalanceTexture = new Texture(
					Gdx.files.internal("balance1.png"));

		if (deleteList == null)
			deleteList = new ArrayList<Integer>();

		if (finishButton == null) {
			finishButton = new Sprite(komodoBalanceTexture, 288 + 80,
					320 + 152, 128, 64);

			finishButton.setPosition((Gdx.graphics.getWidth() * 2 / 5),
					(Gdx.graphics.getHeight() * 3 / 4));
			screenWidth = Gdx.graphics.getWidth();
		}

		if (targetKG == null) {
			targetKG = new Sprite(komodoBalanceTexture, 288, 320 + 152, 80, 80);

			targetKG.setPosition(0,
					Gdx.graphics.getHeight() - targetKG.getHeight());
		}

		if (target == null)
			target = new TargetIndicator(this);

		if (backgroundSprite == null) {
			backgroundSprite = new Sprite(komodoBalanceTexture, 0, 0, 480, 320);
			backgroundSprite.setSize(Gdx.graphics.getWidth(),
					Gdx.graphics.getHeight());
		}

		
		
		if (gameTime == null){
			gameTime = new Time(0, 30);
		}
		gameTime.setMinute(0);
		gameTime.setSecond(30);

	}

	class BalanceWinDialog extends WinDialog {

		public Image finishImage[];

		public BalanceWinDialog(float width, float height, boolean stretch,
				Screen screen, Texture texture,KomodoIsland komodoIsland) {
			super(width, height, stretch, screen, texture,komodoIsland);
			// TODO Auto-generated constructor stub
			finishImage = new Image[3];

			finishImage[0] = new Image("finish", new TextureRegion(
					komodoBalanceTexture, 0, 320 + 152, 96, 96));
			finishImage[1] = new Image("finish", new TextureRegion(
					komodoBalanceTexture, 96, 320 + 152, 96, 96));
			finishImage[2] = new Image("finish", new TextureRegion(
					komodoBalanceTexture, 96 * 2, 320 + 152, 96, 96));

			// finishImage[0].x = 240 - 135;
			// finishImage[0].y = 240 - 135 - 48;
			finishImage[0].x = siKomo.x;
			finishImage[0].y = siKomo.y;

			finishImage[1].x = finishImage[0].x;
			finishImage[1].y = finishImage[0].y;
			finishImage[2].x = finishImage[1].x;
			finishImage[2].y = finishImage[1].y;
		}

		public void setFinishing() {
			removeActor(finishImage[0]);
			removeActor(finishImage[1]);
			removeActor(finishImage[2]);
			if (((GameBalance) screen).balance.basketWeight > ((GameBalance) screen).balance.komodoWeight) {
				addActor(finishImage[0]);
			} else if (((GameBalance) screen).balance.basketWeight < ((GameBalance) screen).balance.komodoWeight) {
				addActor(finishImage[2]);
			} else {
				addActor(finishImage[1]);
			}
		}

	}

	class BalanceLoseDialog extends LoseDialog {
		public Image finishImage[];

		public BalanceLoseDialog(float width, float height, boolean stretch,
				Screen screen, Texture texture,KomodoIsland komodoIsland) {
			super(width, height, stretch, screen, texture,komodoIsland);
			// TODO Auto-generated constructor stub
			finishImage = new Image[3];

			finishImage[0] = new Image("finish", new TextureRegion(
					komodoBalanceTexture, 0, 320 + 152, 96, 96));
			finishImage[1] = new Image("finish", new TextureRegion(
					komodoBalanceTexture, 96, 320 + 152, 96, 96));
			finishImage[2] = new Image("finish", new TextureRegion(
					komodoBalanceTexture, 96 * 2, 320 + 152, 96, 96));

			// finishImage[0].x = 240 - 135;
			// finishImage[0].y = 240 - 135 - 48;
			finishImage[0].x = siKomo.x;
			finishImage[0].y = siKomo.y;

			finishImage[1].x = finishImage[0].x;
			finishImage[1].y = finishImage[0].y;
			finishImage[2].x = finishImage[1].x;
			finishImage[2].y = finishImage[1].y;

		}

		public void setFinishing() {
			removeActor(finishImage[0]);
			removeActor(finishImage[1]);
			removeActor(finishImage[2]);
			if (((GameBalance) screen).balance.basketWeight > ((GameBalance) screen).balance.komodoWeight) {
				addActor(finishImage[0]);
			} else if (((GameBalance) screen).balance.basketWeight < ((GameBalance) screen).balance.komodoWeight) {
				addActor(finishImage[2]);
			} else {
				addActor(finishImage[1]);
			}
		}
	}

	@Override
	public void resize(int arg0, int arg1) {
		// TODO Auto-generated method stub
		super.resize(arg0, arg1);
		camera = new OrthographicCamera(arg0, arg1);
		camera.position.set(Gdx.graphics.getWidth() / 2,
				Gdx.graphics.getHeight() / 2, 0);
	}

	@Override
	public void setCameraToDefault() {
		// TODO Auto-generated method stub
		camera.viewportWidth = Gdx.graphics.getWidth();
		camera.viewportHeight = Gdx.graphics.getHeight();

		camera.position.set(Gdx.graphics.getWidth() / 2,
				Gdx.graphics.getHeight() / 2, 0);
	}

}

class Item {
	public int weight;
	public int acceleration;
	public boolean isReady;
	public Rectangle itemRectangle;
	public Sprite itemSprite;
	public Random rand;

	public Item(int w, int a, int x, Random rand) {
		int rectangleWidth = Gdx.graphics.getWidth() / 10;
		int rectangleHeight = Gdx.graphics.getHeight() / 7;
		weight = w;
		isReady = false;
		acceleration = (Gdx.graphics.getHeight() * a) / Constants.GAME_HEIGHT;
		itemSprite = new Sprite(GameBalance.komodoBalanceTexture);
		this.rand = rand;

		setSprite();
		itemRectangle = new Rectangle(x, Gdx.graphics.getHeight() / -5,
				rectangleWidth, rectangleHeight);
		itemSprite.setPosition(itemRectangle.x, Gdx.graphics.getHeight()
				- itemRectangle.y - itemRectangle.getHeight());
		itemSprite.setSize(rectangleWidth, rectangleHeight);
	}

	public void setSprite() {
		// TODO Auto-generated method stub
		if (weight >= 15) {
			itemSprite.setRegion(0, 320 + 152 + 96, 32, 32);
		} else if (weight >= 10) {
			itemSprite.setRegion(32, 320 + 152 + 96, 32, 32);
		} else {
			int r = rand.nextInt(8);
			switch (r) {
			case 0: {
				itemSprite.setRegion(32 * 2, 320 + 152 + 96, 32, 32);
				break;
			}
			case 1: {
				itemSprite.setRegion(32 * 3, 320 + 152 + 96, 32, 32);
				break;
			}
			case 2: {
				itemSprite.setRegion(32 * 4, 320 + 152 + 96, 32, 32);
				break;
			}
			case 3: {
				itemSprite.setRegion(32 * 5, 320 + 152 + 96, 32, 32);
				break;
			}
			case 4: {
				itemSprite.setRegion(32 * 6, 320 + 152 + 96, 32, 32);
				break;
			}
			case 5: {
				itemSprite.setRegion(32 * 7, 320 + 152 + 96, 32, 32);
				break;
			}
			case 6: {
				itemSprite.setRegion(32 * 8, 320 + 152 + 96, 32, 32);
				break;
			}
			case 7: {
				itemSprite.setRegion(0, 320 + 152 + 96 + 32, 64, 64);
				break;
			}
			}
		}
	}

	public void itemDrop() {
		itemRectangle.y += acceleration;
		itemSprite.setPosition(itemRectangle.x, Gdx.graphics.getHeight()
				- itemRectangle.y - itemRectangle.getHeight());
	}
}

class Balance {
	public int komodoWeight;
	public int basketWeight;
	public Rectangle basketRectangle;
	public int basketWidth;
	public int basketHeight;
	public static final int WEIGHT_LIMIT = 200;
	public Sprite basketSprite;

	public Balance(int kw) {
		komodoWeight = kw;
		basketWidth = 64;
		basketHeight = 152;

		// basketWidth = Gdx.graphics.getWidth() / 5;
		// basketHeight = Gdx.graphics.getHeight() / 4;
		//

		basketRectangle = new Rectangle((Gdx.graphics.getWidth() / 2)
				- (basketWidth / 2), Gdx.graphics.getHeight() - basketHeight,
				basketWidth, basketHeight);
		basketSprite = new Sprite(GameBalance.komodoBalanceTexture, 0, 320, 64,
				152);
		basketSprite.setPosition(basketRectangle.x, Gdx.graphics.getHeight()
				- basketRectangle.y - basketRectangle.getHeight());
		basketSprite.setSize(basketWidth, basketHeight);
	}

	public boolean isTouched() {
		return (basketRectangle.x <= Gdx.input.getX()
				&& basketRectangle.x + basketRectangle.getWidth() >= Gdx.input
						.getX()
				&& basketRectangle.y <= Gdx.input.getY()
				&& basketRectangle.y + basketRectangle.getY() >= Gdx.input
						.getY() && Gdx.input.isTouched());
	}


	public boolean isItemIn(Item item) {
		return (item.itemSprite.getX()+(item.itemSprite.getWidth()/2) >= (basketSprite.getX()- (basketSprite.getWidth()/ 10))
				&& item.itemSprite.getY() >= basketSprite.getY()
				&& item.itemSprite.getY() <= basketSprite.getY() + basketSprite.getHeight() 
				&& item.itemSprite.getX()+(item.itemSprite.getWidth()/2) <= (basketSprite.getX() + (basketSprite.getWidth() * 11 / 10)));
	}

	public boolean isOverWeight() {
		return (basketWeight >= WEIGHT_LIMIT);
	}

	public void increaseWeight(int x) {
		basketWeight += x;
	}

	public void moveBalance(int x) {
		basketRectangle.x += x;
		basketSprite.setPosition(basketRectangle.x, Gdx.graphics.getHeight()
				- basketRectangle.y - basketRectangle.getHeight());
		if (basketSprite.getX() > Gdx.graphics.getWidth()*9/10) {basketSprite.setPosition(Gdx.graphics.getWidth()*9/10, basketSprite.getY());}
		if (basketSprite.getX() < Gdx.graphics.getWidth()/10-basketSprite.getWidth()) {basketSprite.setPosition(Gdx.graphics.getWidth()/10-basketSprite.getWidth(), basketSprite.getY());}
	}

}

class TargetIndicator {
	private GameBalance game;
	private Texture art;

	private TextureRegion[] reds;
	private TextureRegion[] greens;
	private TextureRegion[] yellows;
	private int delta;
	private SpriteBatch batch;

	private final static int RED = 0;
	private final static int GREEN = 1;
	private final static int YELLOW = 2;

	private float posX;
	private float posY;

	public TargetIndicator(GameBalance game) {
		// TODO Auto-generated constructor stub
		this.game = game;
		art = game.komodoBalanceTexture;
		reds = new TextureRegion[10];
		greens = new TextureRegion[10];
		yellows = new TextureRegion[10];
		batch = game.komodoIsland.batch;

		for (int i = 0; i < 10; i++) {
			greens[i] = new TextureRegion(art, 128 + (i * 32), 320, 32, 32);
			reds[i] = new TextureRegion(art, 128 + (i * 32), 320 + 32, 32, 32);
			yellows[i] = new TextureRegion(art, 128 + (i * 32), 320 + 32 * 2,
					32, 32);
		}

		posX = game.targetKG.getWidth() / 2 - 30;
		posY = game.targetKG.getY() - 15;

	}

	public void draw() {
		delta = Math.abs(game.balance.basketWeight - game.balance.komodoWeight);
		if (delta <= 10) {
			drawString(game.balance.basketWeight + "", GREEN, posX, posY);
		} else if (delta <= 20) {
			drawString(game.balance.basketWeight + "", YELLOW, posX, posY);
		} else {
			drawString(game.balance.basketWeight + "", RED, posX, posY);
		}
	}

	public void drawString(String text, int code, float x, float y) {
		batch.begin();
		int index;
		for (int i = 0; i < text.length(); i++) {
			index = (Integer.valueOf(text.charAt(i)));
			if (index >= 48 && index <= 57) {
				if (code == RED) {
					batch.draw(reds[index - 48], x, y, 32, 32);
				} else if (code == YELLOW) {
					batch.draw(yellows[index - 48], x, y, 32, 32);
				} else if (code == GREEN) {
					batch.draw(greens[index - 48], x, y, 32, 32);
				}
				x += 25;
			} else {
				x += 10;
			}

		}
		batch.end();
	}

}
